#pragma once

#include "HSSecuTradeApi.h"
#include <functional>
#include <queue>
#include <chrono>
#include <thread>
#include "MyUtils/tools.hpp"
#include "MyUtils/Thread/ThreadSafeContainer.hpp"
#include "TestCaseInterface.hpp"


typedef std::function<void()> FunctionPtr;

extern MyUtils::Thread::ThreadSafeQueue<FunctionPtr> g_funcQueue;


class TestSecuTradeApi : public CHSSecuTradeApi
{
private:
    CHSSecuTradeSpi *m_pSpi;
    TestCaseInterface *m_pTestCase;
    

public:
    TestSecuTradeApi() {}
    ~TestSecuTradeApi() {}

    /// Description: 删除接口对象本身
    virtual void ReleaseApi() override
    {
        // TODO
    }

    /// Description: 初始化连接
    ///              pszLicFile            通讯证书
    ///              pszSafeLevel          安全级别
    ///              pszPwd                通讯密码
    ///              pszSslFile            SSL证书
    ///              pszSslPwd             SSL密码
    virtual int Init(const char *pszLicFile,
                     const char *pszSafeLevel = "",
                     const char *pszPwd = "",
                     const char *pszSslFile = "",
                     const char *pszSslPwd = "")
    {
        m_pSpi->OnFrontConnected();
        return 0;
    }

    /// Description: API和交易柜台建立连接，连接建立成功后，主线程会等待用户操作子线程退出
    /// Return     : int 0表示连接建立成功，否则表示失败，通过调用GetApiErrorInfo可以获取详细错误信息
    virtual int Join()
    {
        while (true)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    }

    /// Description: 注册回调接口
    /// Input      : pSpi            派生自回调接口类的实例
    virtual void RegisterSpi(CHSSecuTradeSpi *pSpi)
    {
        m_pSpi = pSpi;
    }

    void RegisterTestCase(TestCaseInterface *test_case)
    {
        m_pTestCase = test_case;
    }

    /// 注册前置机网络地址
    ///@param pszFrontAddress：前置机网络地址。
    virtual int RegisterFront(const char *pszFrontAddress)
    {
        // do nothing
        return 0;
    }

    /// 注册Fens网络地址
    /// Input      : pszFensAddress            Fens网络地址
    /// Input      : pszAccountID              账号
    virtual int RegisterFensServer(const char *pszFensAddress, const char *pszAccountID)
    {
        // do nothing
        return 0;
    }

    /// Description: 注册订阅模式
    /// Input      : 订阅方式
    ///                 HS_TERT_RESTART://从本交易日开始重传
    ///                 HS_TERT_RESUME: //从上次收到的续传
    ///                 HS_TERT_QUICK:  //从登录后最新的开始传
    virtual int RegisterSubModel(SUB_TERT_TYPE eSubType)
    {
        // TODO 暂时用不上，实际上也可以不用实现
        return 0;
    }

    /// Description: 获得错误详细信息
    virtual const char *GetApiErrorMsg(int nErrorCode)
    {
        switch (nErrorCode)
        {
        case 0:
            return "success";
            break;

        default:
            return "unknown error";
            break;
        }
        return "unknown error";
    }

#ifdef REQ_FUNCTION2
#undef REQ_FUNCTION2
#endif
#ifdef REQ_FUNCTION
#undef REQ_FUNCTION
#endif

// 定义函数宏
#define REQ_FUNCTION2(functionName, reqParam, RspFiled)                                \
    virtual int functionName(CHSSecu##reqParam *p##reqParam, int nRequestID) override  \
    {                                                                                  \
        CHSSecu##reqParam req_filed = *p##reqParam;                                    \
        auto func = MyUtils::Tools::warpFunction2(&TestCaseInterface::functionName, m_pTestCase, *p##reqParam, nRequestID); \
        g_funcQueue.put(func);                                                         \
        return 0;                                                                      \
    }

#define REQ_FUNCTION(name) \
    REQ_FUNCTION2(Req##name, Req##name##Field, CHSSecuRsp##name##Field)

    /// Description:接入认证
    virtual int ReqAuthenticate(CHSSecuReqAuthenticateField *pReqAuthenticate, int nRequestID) override
    {
        auto func = [=](){
            m_pTestCase->ReqAuthenticate(*pReqAuthenticate, nRequestID);
        };
        g_funcQueue.put(func);
        return 0;
    }
    /// Description:接入认证
    // REQ_FUNCTION(Authenticate)

    virtual int ReqUserLogin(CHSSecuReqUserLoginField *pReqUserLoginField, int nRequestID) override
    {
        auto func = MyUtils::Tools::warpFunction2(&TestCaseInterface::ReqUserLogin, m_pTestCase, *pReqUserLoginField, nRequestID);
        g_funcQueue.put(func);
        return 0;
    }
    // REQ_FUNCTION(UserLogin)


    REQ_FUNCTION(QryStkAcct)

    REQ_FUNCTION(UserPasswordUpdate)
    REQ_FUNCTION(Transfer)
    REQ_FUNCTION(FundTrans)
    REQ_FUNCTION(FundAlloc)
    REQ_FUNCTION(StockTrans)
    REQ_FUNCTION(OrderInsert)
    REQ_FUNCTION(OrderAction)
    REQ_FUNCTION(QryHold)
    REQ_FUNCTION(QryFund)
    REQ_FUNCTION(QryOrder)
    REQ_FUNCTION(QryTrade)
    REQ_FUNCTION(QryStkcode)
    REQ_FUNCTION(QryEquity)
    REQ_FUNCTION(QryEtfcode)
    REQ_FUNCTION(QryEtfcomponent)
    REQ_FUNCTION(QryImpawnDetail)
    /// Description:债券入库集中度查询
    REQ_FUNCTION(QryBondImpawnConc)

    /// Description:现金还款
    REQ_FUNCTION(CashRepay)

    /// Description:可融资金查询
    REQ_FUNCTION(QryEnfinFund)

    /// Description:可融证券查询
    REQ_FUNCTION(QryEnsloStock)

    /// Description:担保证券查询
    REQ_FUNCTION(QryCreditCollateral)

    /// Description:标的证券查询
    REQ_FUNCTION(QryCreditUnderlying)

    /// Description:融资融券费率查询
    REQ_FUNCTION(QryCreditRate)

    /// Description:信用资产信息查询
    REQ_FUNCTION(QryCreditAsset)

    /// Description:两融合约查询
    REQ_FUNCTION(QryCompact)

    /// Description:组合报单录入
    REQ_FUNCTION(ComOrderInsert)

    /// Description:合约展期申请
    REQ_FUNCTION(CompactApply)

    /// Description:新股申购代码查询
    REQ_FUNCTION(QryApplycode)

    /// Description:主柜台资金查询
    REQ_FUNCTION(QryFundUF20)

    /// Description:资金流水查询
    REQ_FUNCTION(QryFundRealJour)

    /// Description:合约流水表查询
    REQ_FUNCTION(QryCompactRealJour)

    /// Description:可买卖数量获取
    REQ_FUNCTION(QryMaxEntradeNum)

    /// Description:股份流水查询
    REQ_FUNCTION(QryStockRealJour)

    /// Description:银行账户查询
    REQ_FUNCTION(QryBankAccount)

    /// Description:港股通客户个人交易汇率查询
    REQ_FUNCTION(QryHKSecurate)

    /// Description:担保提交证券可用数量查询
    REQ_FUNCTION(QryAssureAmount)

    /// Description:担保证券可返回数量查询
    REQ_FUNCTION(QryAssureBackAmount)

    /// Description:对端快速交易中心资金查询
    REQ_FUNCTION(QryFundPeer)

    /// Description:港股非交易报单录入
    REQ_FUNCTION(HkntOrderInsert)

    /// Description:港股非交易报单撤单
    REQ_FUNCTION(HkntOrderAction)

    /// Description:港股非交易委托查询
    REQ_FUNCTION(QryHkntOrder)

    /// Description:港股非交易成交查询
    REQ_FUNCTION(QryHkntTrade)

    /// Description:港股权益信息查询
    REQ_FUNCTION(QryAuthority)

    /// Description:港股公司行为申报参考数量查询
    REQ_FUNCTION(QryHkReferAmount)

    /// Description:港股参考可投票数量查询
    REQ_FUNCTION(QryHkVoteReferAmount)

    /// Description:港股投票当日申报结果查询
    REQ_FUNCTION(QryHkVoteBack)

    /// Description:港股投票截止日投票结果查询
    REQ_FUNCTION(QryHkVoteResult)

    /// Description:银行转账查询
    REQ_FUNCTION(QryTransfer)

    /// Description:银行余额查询
    REQ_FUNCTION(QryBankBalance)

    // REQ_FUNCTION(ReqAuthenticate, OnRspAuthenticate, ReqAuthenticateField)
    // REQ_FUNCTION(ReqUserLogin, OnRspUserLogin, ReqUserLoginField)
    // REQ_FUNCTION(ReqQryStkAcct, OnRspQryStkAcct, ReqQryStkAcctField)

    virtual int BindSessionId(int nBindSessionId) override
    {
        return 0;
    }
};
